/*
   100~300之间201个整数, 现在并发4个工作线程竞争201个整数 
   才用能者多劳的方式 
 */
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define THR_NR   4
#define START    100
#define END		 300
void *job_thread (void * s);
/*
   job > 0, 有main线程有待发放的数值 
	 == 0, 没有待发放的数值 
	 == -1, main线程已经将所有的数值都发放完毕了
 */
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
//所有的线程都可以访问(临界区资源)
static int job = 0;
int main (void)
{
	pthread_t tids[THR_NR] = {0};
	int i = 0;
	int err = 0;
	//并发4个工作线程
	for (i = 0; i < THR_NR; i++) {
		err = pthread_create (tids + i, NULL, job_thread, NULL);
		if (err) {
			fprintf (stderr, "pthread_create():%s\n", strerror(err));
			exit(1);
		}
	}

	//负责给4个工作线程发送数值
	for (i = START; i <= END; i++) {
		//将i依次赋值给job 
		//如果pthread_mutex_lock返回, 证明竞争到资源了
		pthread_mutex_lock (&mut);
		while (job != 0) {//轮询, 轮询job的值是否为0, 不为0则一直轮询
			pthread_mutex_unlock (&mut);
			pthread_mutex_lock (&mut);
		}
		job = i;
		pthread_mutex_unlock (&mut);
	}
	
	//等待job==0, 最后一个数值计算完毕
	pthread_mutex_lock (&mut);
	while (job > 0) { //有待发放的数值
		pthread_mutex_unlock (&mut);
		pthread_mutex_lock (&mut);
	}
	job = -1;
	pthread_mutex_unlock (&mut);

	//等待线程的汇合
	for (i = 0; i < THR_NR; i++) 
	{
		pthread_join (tids[i], NULL);
	}
	pthread_mutex_destroy (&mut);

	return 0;
}

static int is_primer (int n) {
	int i = 0;
	if (n < 2) {
		return 0;
	}
	for (i = 2; i < n; i++) {
		if (n % i == 0) {
			return 0;
		}
	}
	return 1;
}

void *job_thread (void * s)
{
	int n = 0;
	while (1) {
		pthread_mutex_lock(&mut);
		if (-1 == job) {
			pthread_mutex_unlock (&mut);
			break;
		}
		if (0 == job) {
			//main线程还没有将数值发放完毕
			pthread_mutex_unlock (&mut);
			continue;
		}
		n = job;
		sleep (1);
		job = 0;//任务已经被取走了
		pthread_mutex_unlock (&mut);

		if (is_primer(n)) {
			printf ("%d is a primer\n", n);
		}
	}
	return NULL;
}
